<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>barChart</title>
    <script src="D3.js"></script>
    <script src="dataCoV.js"></script>
    <script src="ChinaGEoJson.js"></script>
    <style>
        .domain {
            display: none;
        }
    </style>
</head>


<body>
    <div style="display: flex;justify-content:space-around;font-size: 18px;">
        <div id="time"></div>
        <div>中国疫情确诊人数(不含湖北省)</div>
        <div>d3.js数据可视化</div>
    </div>
    <div id="barChart"></div>
</body>

<script>
    /**
     * 去掉湖北省
     */
    let dataCoV = [];
    for (let i = 0; i < data123.length; i++) {
        let data = data123[i].filter(item => item.provinceCode != "420000")
        if (data.length != 0) {
            dataCoV.push(data)
        }
    }


    let index = 0;
    let DATA = dataCoV[index]; //数据
    const SVG_WIDTH = 1400; //svg宽度
    const SVG_HEIGHT = 600; //svg高度
    const RECT_WIDTH = 30; //矩形宽度
    const RECT_SPACE = 10; //间隔
    const LABEL_WIDTH = 10; //标签宽度
    const DATA_WIDTH = 100; //标签宽度
    const LEFT_WIDTH = 50; //左边平移宽度
    const INTERVAL_TIME = 100; //刷新间隔时间（毫秒）

    //创建SVG图像
    let svg = d3.select("#barChart")
        .append("svg")
        .attr('width', SVG_WIDTH)
        .attr('height', SVG_HEIGHT)

    // 坐标轴g
    let gAxis = svg.append("g")
        .attr("transform", `translate(${LEFT_WIDTH}, ${SVG_HEIGHT-30})`)

    //分级统计图g
    let gChoropleth = svg.append('g')
        .attr("transform", `translate(${SVG_WIDTH / 2}, 100)`)

    //条形图g
    let gBar = svg.append('g')

    //绘制坐标轴
    let axis = d3.axisBottom()


    /**
     *  分级统计图绘制 
     * */

    const projection = d3.geoMercator().fitExtent(
        [
            [0, 0],
            [SVG_WIDTH / 2, SVG_HEIGHT],
        ], ChinaGEoJson);

    const pathGenerator = d3.geoPath()
        .projection(projection); //配置上投影

    let mapG = gChoropleth.selectAll("path")
        .data(ChinaGEoJson.features) //数据绑定
        .enter()
        .append("path")
        .attr("d", pathGenerator) //绘制path
        .attr("stroke-width", 0.1)
        .attr("stroke", "#000000")

    // 显示渐变矩形条
    const linearGradient = gChoropleth.append("defs")
        .append("linearGradient")
        .attr("id", "linearColor")
        //颜色渐变方向
        .attr("x1", "0%")
        .attr("y1", "100%")
        .attr("x2", "0%")
        .attr("y2", "0%");
    // //设置矩形条开始颜色
    linearGradient.append("stop")
        .attr("offset", "0%")
        .attr("stop-color", '#FFDEAD');
    // //设置结束颜色
    linearGradient.append("stop")
        .attr("offset", "100%")
        .attr("stop-color", '#800000');
    svg.append("rect")
        //x,y 矩形的左上角坐标
        .attr("x", SVG_WIDTH - 50)
        .attr("y", SVG_HEIGHT - 86) // 83为矩形的高
        //矩形的宽高
        .attr("width", 16)
        .attr("height", 83)
        //引用上面的id 设置颜色
        .style("fill", "url(#" + linearGradient.attr("id") + ")");

    //比例尺
    let scaleColor = d3.scaleLinear()
        .domain([0, 3000]) //设置1-5的线性定义域
        .range(['#FFDEAD', '#800000']) //设置0-100的线性值域

    //定时器
    let interval = window.setInterval(() => {

        //比例尺
        let scale = d3.scaleLinear()
            .domain([0, d3.max(dataCoV[index], d => d.confirmed)])
            .range([0, SVG_WIDTH - DATA_WIDTH - LABEL_WIDTH])



        //绑定坐标轴比例尺
        axis.scale(scale);

        // 绘制坐标轴
        axis(gAxis)

        gAxis.selectAll("line")
            .attr("y2", -1000)
            .attr("stroke", "#ccc")

        gAxis.selectAll("text")
            .attr("stroke", "#ccc")


        //排序
        let data = dataCoV[index].sort((a, b) => b.confirmed - a.confirmed);

        //分级统计图上色
        mapG.attr("fill", d => {
            let countiesCases = dataCoV[index].filter(item => item.provinceCode === d.properties.adcode);
            if (countiesCases.length != 0) {
                return scaleColor(countiesCases[0].confirmed)
            }
            return '#FFDEAD'
        });

        //时间显示
        document.getElementById("time").innerText = dataCoV[index][0].date;

        /**
         * 删除数据
         **/
        gBar.selectAll('g')
            .data(data, d => d.province)
            .exit()
            .remove()

        /**
         *添加数据
         **/
        let groupAppend = gBar.selectAll('g')
            .data(data, d => d.province)
            .enter()
            .append('g')
            .attr("transform", (d, i) => `translate(${LEFT_WIDTH}, ${i * (RECT_WIDTH + RECT_SPACE)} )`)

        const color = `rgba( ${Math.random() * 255 },${ Math.random() * 255 },${ Math.random() * 255 })`

        groupAppend.append("rect")
            .attr("x", 0)
            .attr("y", RECT_SPACE)
            .attr("rx", 10)
            .attr("ry", 10)
            .attr("width", d => scale(d.confirmed))
            .attr("height", RECT_WIDTH)
            .attr("fill", color)

        groupAppend.append("text")
            .attr("x", d => scale(d.confirmed) + LABEL_WIDTH + 10)
            .attr("y", RECT_WIDTH / 2 + RECT_SPACE)
            .attr("dy", ".35em")
            .text(d => d.confirmed);

        groupAppend.append("text")
            .attr("class", "name")
            .attr("font-weight", 600)
            .attr("fill", "#FFFFFF")
            .attr("stroke", color)
            .attr("x", 0)
            .attr("y", RECT_SPACE)
            .attr('text-anchor', "end")
            .attr("dy", ".35em")
            .text(d => d.province);

        /**
         * 数据更新
         **/
        let group = gBar.selectAll('g')
            .data(data, d => d.province)
            .transition()
            .attr("transform", (d, i) => `translate(${LEFT_WIDTH}, ${i * (RECT_WIDTH + RECT_SPACE)} )`)

        group.select("rect")
            .attr("width", d => scale(d.confirmed))

        group.select("text")
            .attr("x", d => scale(d.confirmed) + LABEL_WIDTH + 10)
            .text(d => d.confirmed);

        group.select(".name")
            .attr("x", d => scale(d.confirmed) - LABEL_WIDTH)
            .text(d => d.province);

        index = index + 1;
        if (index === dataCoV.length - 1) {
            clearTimeout(interval);
        }
    }, INTERVAL_TIME)
</script>

</html>